
pub struct C24Data2 {

    pub nums: [f32; 4],
    pub ops: [u8; 3],

    pub len: u8,
}

fn calc(a: f32, b: f32, op: u8) -> Option<f32> {

    match op {

        b'+' => {
            println!("计算:{} + {}", a, b);
            Some(a + b)
        }
        b'-' => {
            println!("计算:{} - {}", a, b);
            Some(a - b)
        }
        b'*' => {
            println!("计算{} * {}", a, b);
            Some(a * b)
        }
        b'/' => {
            if b <= 1e-6 {
                println!("b==0");
                None
            } else {
                println!("计算{} / {}", a, b);
                Some(a / b)
            }
            
        }
        _ => {
            println!("无法处理的运算符");
            None
        }
    }
}

fn is_primary(op: u8) -> bool {
    return (op == b'*') || (op == b'/');
}

impl C24Data2 {

    pub fn new(a: f32, ab_op: u8, b: f32, bc_op: u8, c: f32, cd_op: u8, d: f32) -> Self {
        Self {
            nums: [a, b, c, d],
            ops: [ab_op, bc_op, cd_op],
            len: 3, // 运算符数量
        }
    }

    pub fn calc24(&mut self) {

    }

    pub fn calc(&mut self) -> Option<f32> {

        if self.len == 0 {
            return Some(self.nums[0]);
        }

        let mut op_index = 0;
        while op_index < self.len {
            if is_primary( self.ops[op_index as usize] ) {
                break;
            }
            op_index += 1;
        }
        if op_index >= self.len {
            op_index = 0;
        }

        let left = self.nums[ op_index as usize ];
        let right = self.nums[(op_index + 1) as usize];

        let v = calc(left, right, self.ops[op_index as usize])?;
        self.nums[op_index as usize] = v;

        if ((op_index + 2) as usize) < self.nums.len() {
            array_left(&mut self.nums, (op_index + 2) as usize);
        }
        if ((op_index + 1) as usize) < self.ops.len() {
            array_left(&mut self.ops, (op_index + 1) as usize);
        }
        self.len -= 1;

        self.calc()
    }
}


fn array_left<T: Copy>(nums: &mut[T], index: usize) {
    let n = nums.len() - index;
    for i in 0..n {
        nums[index - 1 + i] = nums[index + i];
    }
}

pub fn c242_test() {

    let mut data = C24Data2::new(1.0, b'+', 2.0, b'+', 3.0, b'/', 4.0);
    let v = data.calc();
    println!("{:#?}", v);
}
